package in

import (
	"fmt"
	"log"
	"strconv"
	"strings"
)

type Datas []G

func (datas Datas) Keys() (keys KeySet) {
	keys = make(KeySet)
	for _, d := range datas {
		for n := range d {
			keys[n] = true
		}
		break
	}
	return
}

func (datas Datas) AutoTrans(bottle *SqlBottle, name string) Datas {
	if bottle.Tp == "mysql" {
		kmap := make(map[string]int)
		for _, v := range bottle.Query(OperWith("").Set(G{"raw": "DESCRIBE " + name})) {
			key := strings.TrimSpace(string(v["Field"].([]byte)))
			v := strings.TrimSpace(string(v["Type"].([]byte)))
			if v == "text" {
				kmap[key] = 0
			} else if strings.HasPrefix(v, "int") {
				kmap[key] = 1
			} else if strings.HasPrefix(v, "varchar") {
				kmap[key] = 0
			} else if strings.HasPrefix(v, "bool") {
				kmap[key] = 2
			} else if strings.HasPrefix(v, "long") {
				kmap[key] = 3
			} else {
				log.Fatal("Type:", v)
			}
		}
		for _, valueG := range datas {
			for k, v := range valueG {
				switch kmap[k] {
				case 1:
					if vl, err := strconv.Atoi(string(v.([]byte))); err == nil {
						valueG[k] = vl
					}
				case 2:
					if string(v.([]byte)) == "1" {
						valueG[k] = true
					} else {
						valueG[k] = false
					}
				default:
					// ColorL(k, v)
					// ColorD(valueG)
					switch c := v.(type) {
					case []uint8:
						valueG[k] = string(v.([]byte))
					case int:
						valueG[k] = int(c)
					case string:
						valueG[k] = fmt.Sprint(c)
					case float32:
						valueG[k] = float32(c)
					case float64:
						valueG[k] = float64(c)
					default:
						valueG[k] = string(v.([]byte))

					}

				}
			}
		}
	}
	return datas
}

func (datas Datas) Nodes(connectedKeys ...string) (nodes Nodes) {

	for no, data := range datas {
		node, err := NewNode(data)
		if err != nil {
			log.Println("datas -> nodes error:", err)
		}
		node.ID = no
		nodes = append(nodes, node)
	}
	if len(connectedKeys) == 0 {
		for co, node := range nodes {
			for _, otherNode := range nodes[co:] {
				if otherNode != node {
					for k := range node.Data {
						if v, ok := otherNode.Data[k]; ok && v == node.Data[k] {
							node.connected = append(node.connected, otherNode)
							node.ConnectedKeys[k] = true
							otherNode.ConnectedKeys[k] = true
							otherNode.whoconnected = append(otherNode.whoconnected, node)
						}
					}
				}
			}
		}
	} else {
		for co, node := range nodes {
			for _, otherNode := range nodes[co:] {
				if otherNode != node {
					for _, k := range connectedKeys {
						if v, ok := otherNode.Data[k]; ok && v == node.Data[k] {
							node.connected = append(node.connected, otherNode)
							node.ConnectedKeys[k] = true
							otherNode.ConnectedKeys[k] = true
							otherNode.whoconnected = append(otherNode.whoconnected, node)
						}
					}
				}
			}
		}
	}
	return
}
